package com.sduept.nwld.dataserver.controller.base.secondary;

import com.alibaba.fastjson.JSONObject;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.model.core.PowerSystemResource;
import com.sduept.cim.model.core.Substation;
import com.sduept.cim.model.extend.LineSegment;
import com.sduept.cim.model.generation.GeneratingUnit;
import com.sduept.cim.model.generation.HydroGeneratingUnit;
import com.sduept.cim.model.protection.ProtectionEquipment;
import com.sduept.cim.model.wires.*;
import com.sduept.core.dao.SuperDAO;
import com.sduept.core.entity.IdentifiedObject;
import com.sduept.nwld.dataserver.manager.cim.CimManager;
import com.sduept.utils.PingYinUtil;
import org.apache.commons.lang.StringUtils;

import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Named
@ViewScoped
public class ProtectDevRelationView extends AbstractController {

	private static final long serialVersionUID = 2995195154616499966L;
	@Autowired
	private SuperDAO dao;
	@Autowired
	private CimManager cim;

	private LazyDataModel<ProtectionEquipment> model;
	private List<ProtectionEquipment> protect = new ArrayList<>();
	private Map<String, List<String>> cimstation = new HashMap<>();
	// 保护型号
	private List<String> devTypes = new ArrayList<>();
	private Map<String, List<String>> cimdevtype = new HashMap<>();
	// 一次设备
	private ACLineSegment acs = null;// 线路
	private Breaker breaker = null;// 断路器
	private BusbarSection mx = null;// 母线
	private PowerTransformer byq = null;// 变压器
	private HydroGeneratingUnit fdj = null;// 发电机
	private Compensator dkq = null;// 电抗器

	private List<IdentifiedObject> equipments = new ArrayList<>();
	private Map<String, List<String>> primEquipments = new HashMap<>();
	// 厂家
	private List<String> devManufacturers = new ArrayList<>();
	private Map<String, List<String>> devManufacturerMap = new HashMap<>();

	// 一次设备类型
	private List<String> protectedTypes = new ArrayList<>();
	// 保护类型
	private List<String> types = new ArrayList<>();
	private ProtectionEquipment selected = null;
	private ProtectionEquipment created = null;
	// 查询变电站名
	private String substationName;
	// 查询保护名
	private String protectedName;
	private String privateSubStationName;
	private int count = 0;

	private boolean withOutSubstation = false;
	private boolean withOutPrim = false;

	private int selectedVoltage = 0;// 选择的电压等级

	@PostConstruct
	private void init() {
		types.add("");
		initBaseData();
		queryAll();
	}

	/**
	 * 重置
	 */
	public void reset() {
		withOutSubstation = false;
		withOutPrim = false;
		substationName = "";
		protectedName = "";
		privateSubStationName = "";
		selectedVoltage = 0;
		queryAll();
	}

	/**
	 * 加载页面基础选择数据
	 */
	private void initBaseData() {
		List<?> allProtectedName = dao.nativeQuery("select distinct protected_name from t_cim_protection_equipment where protected_name is not null");
		for (Object object : allProtectedName) {
			String key = PingYinUtil.getPingYinHeader(object + "");
			List<String> ss = primEquipments.get(key);
			if (ss == null) {
				ss = new ArrayList<>();
				primEquipments.put(key, ss);
			}
			ss.add(object + "");
		}

		List<?> AllProtectedTypes = dao.nativeQuery("select protected_type from t_cim_protection_equipment where protected_type is not null and protected_type !=''  group by protected_type");
		for (Object o : AllProtectedTypes) {
			protectedTypes.add(o.toString());
		}

		List<?> Alltypes = dao.nativeQuery("select type from t_cim_protection_equipment where type is not null and type !='' group by type");
		for (Object o : Alltypes) {
			types.add(o.toString());
		}

		List<?> allDev = dao.nativeQuery("select dev_manufacturer from t_cim_protection_equipment where dev_manufacturer is not null and dev_manufacturer != '' group by dev_manufacturer");
		for (Object o : allDev) {
			devManufacturers.add(o.toString());
		}
		for (int i = 0; i < devManufacturers.size(); i++) {
			String key = PingYinUtil.getPingYinHeader(devManufacturers.get(i));
			List<String> ss = devManufacturerMap.get(key);
			if (ss == null) {
				ss = new ArrayList<>();
				devManufacturerMap.put(key, ss);
			}
			ss.add(devManufacturers.get(i));
		}

		List<?> allType = dao.nativeQuery("select dev_type from t_cim_protection_equipment where dev_type is not null and dev_type !='' group by dev_type");
		for (Object o : allType) {
			devTypes.add(o.toString());
		}
	}

	/**
	 * 获取所有保护
	 */
	public void queryAll() {
		protect.clear();
		model = new LazyDataModel<ProtectionEquipment>() {
			private static final long serialVersionUID = 3423812002225330289L;

			@Override
			public List<ProtectionEquipment> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
				count = first;
				protect = cim.listAllProtectionEquipments(new int[] { first, first + pageSize });
				return protect;
			}

			@Override
			public ProtectionEquipment getRowData(String rowKey) {
				for (ProtectionEquipment t : protect) {
					if (t.getId().equals(rowKey)) {
						return t;
					}
				}
				return null;
			}

			@Override
			public Object getRowKey(ProtectionEquipment object) {
				for (ProtectionEquipment t : protect) {
					if (t.getId().equals(object.getId())) {
						return t;
					}
				}
				return null;
			}
		};
		model.setRowCount(cim.countAllProtection());
	}

	/**
	 * 搜索中用到：展示变电站名
	 *
	 * @param query
	 * @return
	 */
	public List<String> completeStationNames(String query) {
		List<String> results = new ArrayList<String>();
		for (String s : cimstation.keySet()) {
			if (s.startsWith(query))
				results.addAll(cimstation.get(s));
		}
		return results;
	}

	/**
	 * 展示生产厂家名称
	 *
	 * @param query
	 * @return
	 */
	public List<String> completeDevManufacturer(String query) {
		List<String> results = new ArrayList<String>();
		for (String s : devManufacturerMap.keySet()) {
			if (s.startsWith(query))
				results.addAll(devManufacturerMap.get(s));
		}
		return results;
	}

	/**
	 * 自动补全
	 *
	 * @param query
	 * @return
	 */
	public List<String> completeDevTypes(String query) {
		List<String> results = new ArrayList<String>();
		for (String s : cimdevtype.keySet()) {
			if (s.startsWith(query))
				results.addAll(cimdevtype.get(s));
		}
		return results;
	}

	public void saveNew() {
		if (!created.getName().equals("")) {
			created = dao.create(created, ProtectionEquipment.class);
//			protect.add(0, created);
			queryAll();
			addSuccessMessage("保存成功");
			created = null;
		} else {
			addErrorMessage("保存失败，数据为空");
		}
	}

	public void update() {
		if (selected != null) {
			dao.update(selected, ProtectionEquipment.class);
			addSuccessMessage("保存成功");
		}
		selected = null;
	}

	public void createNew() {
		created = new ProtectionEquipment();
	}

	// 根据变电站名字搜索
	public void queryBySubstationName() {
		protect.clear();
		if (StringUtils.isNotEmpty(substationName) || StringUtils.isNotEmpty(protectedName) || StringUtils.isNotEmpty(privateSubStationName) || withOutSubstation || withOutPrim
				|| selectedVoltage != 0) {
			model = new LazyDataModel<ProtectionEquipment>() {
				private static final long serialVersionUID = 3423812002225330289L;

				@Override
				public List<ProtectionEquipment> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
					count = first;
					protect = cim.getProtectionEquipmentBySubstationName(substationName, protectedName, privateSubStationName, withOutSubstation, withOutPrim, selectedVoltage,
							new int[] { first, first + pageSize });
					return protect;
				}

				@Override
				public ProtectionEquipment getRowData(String rowKey) {
					for (ProtectionEquipment t : protect) {
						if (t.getId().equals(rowKey)) {
							return t;
						}
					}
					return null;
				}

				@Override
				public Object getRowKey(ProtectionEquipment object) {
					for (ProtectionEquipment t : protect) {
						if (t.getId().equals(object.getId())) {
							return t;
						}
					}
					return null;
				}
			};
			model.setRowCount(cim.countEquipmentBySubstationName(substationName, protectedName, privateSubStationName, withOutSubstation, withOutPrim, selectedVoltage));
		} else {
			queryAll();
		}

	}

	/**
	 * 打开选择变电站模态框
	 */
	public void chooseSubStation() {
		Map<String, Object> options = new HashMap<String, Object>();
		options.put("resizable", false);
		options.put("draggable", false);
		options.put("modal", true);
		options.put("width", 600);
		options.put("height", 400);
		Map<String, List<String>> params = new HashMap<>();
		openDialog("/ui/common/equipment_selector_single",  params,options);
	}

	public void chooseEquipment() {
		Map<String, Object> options = new HashMap<String, Object>();
		options.put("resizable", false);
		options.put("draggable", false);
		options.put("modal", true);
		options.put("width", 600);
		options.put("height", 400);
		Map<String, List<String>> params = new HashMap<>();
		List<String> s = new ArrayList<>();
		if (selected != null) {
			s.add(selected.getSubId());
		}
		params.put("stationId", s);
		openDialog("/ui/common/equipment_selector_single",  params,options);
	}

	public void chooseEquipmentNew() {
		Map<String, Object> options = new HashMap<String, Object>();
		options.put("resizable", false);
		options.put("draggable", false);
		options.put("modal", true);
		options.put("width", 600);
		options.put("height", 400);
		Map<String, List<String>> params = new HashMap<>();
		List<String> s = new ArrayList<>();
		if (StringUtils.isNotEmpty(created.getSubId())) {
			if (created != null) {
				s.add(created.getSubId());
			}
			params.put("stationId", s);
			openDialog("/ui/common/equipment_selector_single",  params,options);
		} else {
			addErrorMessage("请先选择变电站");
		}
	}

	/**
	 * 清除选择的一次设备
	 */
	public void cleanChooseEquipment() {
		selected.setProtectedName(null);
		selected.setProtectedId(null);
	}

	/**
	 * 清除选择的一次设备
	 */
	public void cleanChooseEquipmentNew() {
		created.setProtectedName(null);
		created.setProtectedId(null);
	}

	/**
	 * 编辑页面选择变电站
	 *
	 * @param event
	 */
	public void onSelectorChosenSubstation(SelectEvent event) {
		// 返回的是选择的对象
		try {
			Substation chooseSubStation = (Substation) event.getObject();
			selected.setSubName(chooseSubStation.getName());
			selected.setSubId(chooseSubStation.getId());
		} catch (Exception e) {
			if (e instanceof ClassCastException) {
				addErrorMessage("选择必须为变电站！");
			}
			return;
		}
	}

	/**
	 * 编辑页面选择变电站
	 * dialog调用
	 * @param event
	 */
	public void onSelectorChosenSubstation4Dialog() {
		String data = getParameter("data");
		String className = getParameter("className");
		if (Substation.class.getSimpleName().equals(className)) {
			Substation chooseSubStation = JSONObject.parseObject(data, Substation.class);
			selected.setSubName(chooseSubStation.getName());
			selected.setSubId(chooseSubStation.getId());
		} else {
			addErrorMessage("选择必须为变电站！");
		}
	}

	/**
	 * 新建页面选择变电站
	 *
	 * @param event
	 */
	public void onNewChosenSubstation(SelectEvent event) {
		// 返回的是选择的对象
		try {
			Substation chooseSubStation = (Substation) event.getObject();
			created.setSubName(chooseSubStation.getName());
			created.setSubId(chooseSubStation.getId());
		} catch (Exception e) {
			if (e instanceof ClassCastException) {
				addErrorMessage("选择必须为变电站！");
			}
			return;
		}
	}

	/**
	 * 新建页面选择变电站
	 * dialog调用
	 * @param event
	 */
	public void onNewChosenSubstation4Dialog() {
		String data = getParameter("data");
		String className = getParameter("className");
		if (Substation.class.getSimpleName().equals(className)) {
			Substation chooseSubStation = JSONObject.parseObject(data, Substation.class);
			created.setSubName(chooseSubStation.getName());
			created.setSubId(chooseSubStation.getId());
		} else {
			addErrorMessage("选择必须为变电站！");
		}
	}

	/**
	 * 编辑页面选择一次设备，并给一次设备类型选择框附默认值
	 *
	 * @param event
	 */
	public void onSelectorChosenEquipment(SelectEvent event) {
		// 返回的是选择的对象
		try {
			if (event.getObject() instanceof PowerSystemResource) {
				PowerSystemResource chooseEqum = (PowerSystemResource) event.getObject();
				selected.setProtectedName(chooseEqum.getName());
				selected.setProtectedId(chooseEqum.getId());
				String equipmentTpype = queryAllEquipments(chooseEqum.getId());
				selected.setProtectedType(equipmentTpype);
			} else if (event.getObject() instanceof LineSegment) {
				LineSegment chooseEqum = (LineSegment) event.getObject();
				selected.setProtectedName(chooseEqum.getName());
				selected.setProtectedId(chooseEqum.getId());
				String equipmentTpype = queryAllEquipments(chooseEqum.getId());
				selected.setProtectedType(equipmentTpype);
			}
		} catch (Exception e) {
			if (e instanceof ClassCastException) {
				addErrorMessage("选择必须为一次设备！");
			}
			return;
		}
	}

	/**
	 * 编辑页面选择一次设备，并给一次设备类型选择框附默认值
	 * dialog调用
	 * @param event
	 */
	public void onSelectorChosenEquipment4Dialog() {
		String data = getParameter("data");
		String classPath = getParameter("classPath");
		Class<?> c = null;
		try {
			c = Class.forName(classPath);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		if(Substation.class.isAssignableFrom(c)) {
			Substation chooseEqum = JSONObject.parseObject(data, Substation.class);
			selected.setProtectedName(chooseEqum.getName());
			selected.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			selected.setProtectedType(equipmentTpype);
		}else if(ACLineSegment.class.isAssignableFrom(c)) {
			ACLineSegment chooseEqum = JSONObject.parseObject(data, ACLineSegment.class);
			selected.setProtectedName(chooseEqum.getName());
			selected.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			selected.setProtectedType(equipmentTpype);
		}else if(DcLinesegment.class.isAssignableFrom(c)) {
			DcLinesegment chooseEqum = JSONObject.parseObject(data, DcLinesegment.class);
			selected.setProtectedName(chooseEqum.getName());
			selected.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			selected.setProtectedType(equipmentTpype);
		} else if (Breaker.class.isAssignableFrom(c)) {
			Breaker chooseEqum = JSONObject.parseObject(data, Breaker.class);
			selected.setProtectedName(chooseEqum.getName());
			selected.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			selected.setProtectedType(equipmentTpype);
		} else if (BusbarSection.class.isAssignableFrom(c)) {
			BusbarSection chooseEqum = JSONObject.parseObject(data, BusbarSection.class);
			selected.setProtectedName(chooseEqum.getName());
			selected.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			selected.setProtectedType(equipmentTpype);
		} else if (PowerTransformer.class.isAssignableFrom(c)) {
			PowerTransformer chooseEqum = JSONObject.parseObject(data, PowerTransformer.class);
			selected.setProtectedName(chooseEqum.getName());
			selected.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			selected.setProtectedType(equipmentTpype);
		} else if (ProtectionEquipment.class.isAssignableFrom(c)) {
			ProtectionEquipment chooseEqum = JSONObject.parseObject(data, ProtectionEquipment.class);
			selected.setProtectedName(chooseEqum.getName());
			selected.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			selected.setProtectedType(equipmentTpype);
		} else if (GeneratingUnit.class.isAssignableFrom(c)) {
			GeneratingUnit chooseEqum = JSONObject.parseObject(data, GeneratingUnit.class);
			selected.setProtectedName(chooseEqum.getName());
			selected.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			selected.setProtectedType(equipmentTpype);
		} else {
			addErrorMessage("选择必须为一次设备！");
		}
//		if (PowerSystemResource.class.isAssignableFrom(c)) {
//			PowerSystemResource chooseEqum = JSONObject.parseObject(data, PowerSystemResource.class);
//			selected.setProtectedName(chooseEqum.getName());
//			selected.setProtectedId(chooseEqum.getId());
//			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
//			selected.setProtectedType(equipmentTpype);
//		} else if (LineSegment.class.isAssignableFrom(c)) {
//			LineSegment chooseEqum = JSONObject.parseObject(data, LineSegment.class);
//			selected.setProtectedName(chooseEqum.getName());
//			selected.setProtectedId(chooseEqum.getId());
//			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
//			selected.setProtectedType(equipmentTpype);
//		} else {
//			addErrorMessage("选择必须为一次设备！");
//		}
	}

	public void onSelectorChosenEquipmentNew(SelectEvent event) {
		// 返回的是选择的对象
		try {
			if (event.getObject() instanceof PowerSystemResource) {
				PowerSystemResource chooseEqum = (PowerSystemResource) event.getObject();
				created.setProtectedName(chooseEqum.getName());
				created.setProtectedId(chooseEqum.getId());
				String equipmentTpype = queryAllEquipments(chooseEqum.getId());
				created.setProtectedType(equipmentTpype);
			} else if (event.getObject() instanceof LineSegment) {
				LineSegment chooseEqum = (LineSegment) event.getObject();
				created.setProtectedName(chooseEqum.getName());
				created.setProtectedId(chooseEqum.getId());
				String equipmentTpype = queryAllEquipments(chooseEqum.getId());
				created.setProtectedType(equipmentTpype);
			}
		} catch (Exception e) {
			if (e instanceof ClassCastException) {
				addErrorMessage("选择必须为一次设备！");
			}
			return;
		}
	}

	/**
	 * dialog调用
	 * @param event
	 */
	public void onSelectorChosenEquipmentNew4Dialog() {
		String data = getParameter("data");
		String classPath = getParameter("classPath");
		Class<?> c = null;
		try {
			c = Class.forName(classPath);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		Object dataObj = JSONObject.parseObject(data, c);// 数据对象
		if (dataObj instanceof LineSegment) {
			LineSegment chooseEqum = (LineSegment) dataObj;
			created.setProtectedName(chooseEqum.getName());
			created.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			created.setProtectedType(equipmentTpype);
		} else if (dataObj instanceof PowerSystemResource) {
			PowerSystemResource chooseEqum = (PowerSystemResource) dataObj;
			created.setProtectedName(chooseEqum.getName());
			created.setProtectedId(chooseEqum.getId());
			String equipmentTpype = queryAllEquipments(chooseEqum.getId());
			created.setProtectedType(equipmentTpype);
		} else {
			addErrorMessage("选择必须为一次设备！");
		}
	}

	/**
	 * 根据id查询一次设备
	 *
	 * @param sid
	 */
	private String queryAllEquipments(String sid) {
		String type = "";
		acs = cim.getAcLineSegmentById(sid);// 线路
		if (acs != null) {
			type = "线路";
			return type;
		}
		breaker = cim.getBreakerByBreakerId(sid);// 断路器
		if (breaker != null) {
			type = "断路器";
			return type;
		}
		mx = cim.getBusbarSectionsById(sid);// 母线
		if (mx != null) {
			type = "母线";
			return type;
		}
		byq = cim.getPowerTransformersById(sid);// 变压器
		if (byq != null) {
			type = "变压器";
			return type;
		}
		fdj = cim.getHydroGeneratingUnitById(sid);// 发电机
		if (fdj != null) {
			type = "发电机";
			return type;
		}
		dkq = cim.getCompensatorById(sid);// 电抗器
		if (dkq != null) {
			type = "电抗器";
			return type;
		}
		if (StringUtils.isEmpty(type)) {
			type = "未知";
			return type;
		}
		return type;
	}

	public int getIndex(ProtectionEquipment p) {
		return protect.indexOf(p) + 1 + count;
	}

	public List<String> getDevTypes() {
		return devTypes;
	}

	public void setDevTypes(List<String> devTypes) {
		this.devTypes = devTypes;
	}

	public List<ProtectionEquipment> getProtect() {
		return protect;
	}

	public void setProtect(List<ProtectionEquipment> protect) {
		this.protect = protect;
	}

	public ProtectionEquipment getSelected() {
		return selected;
	}

	public void setSelected(ProtectionEquipment selected) {
		this.selected = selected;
	}

	public List<String> getProtectedTypes() {
		return protectedTypes;
	}

	public void setProtectedTypes(List<String> protectedTypes) {
		this.protectedTypes = protectedTypes;
	}

	public List<String> getTypes() {
		return types;
	}

	public void setTypes(List<String> types) {
		this.types = types;
	}

	public List<IdentifiedObject> getEquipments() {
		return equipments;
	}

	public void setEquipments(List<IdentifiedObject> equipments) {
		this.equipments = equipments;
	}

	public ProtectionEquipment getCreated() {
		return created;
	}

	public void setCreated(ProtectionEquipment created) {
		this.created = created;
	}

	public LazyDataModel<ProtectionEquipment> getModel() {
		return model;
	}

	public void setModel(LazyDataModel<ProtectionEquipment> model) {
		this.model = model;
	}

	public String getSubstationName() {
		return substationName;
	}

	public void setSubstationName(String substationName) {
		this.substationName = substationName;
	}

	public String getProtectedName() {
		return protectedName;
	}

	public void setProtectedName(String protectedName) {
		this.protectedName = protectedName;
	}

	public boolean isWithOutPrim() {
		return withOutPrim;
	}

	public void setWithOutPrim(boolean withOutPrim) {
		this.withOutPrim = withOutPrim;
	}

	public boolean isWithOutSubstation() {
		return withOutSubstation;
	}

	public void setWithOutSubstation(boolean withOutSubstation) {
		this.withOutSubstation = withOutSubstation;
	}

	public int getSelectedVoltage() {
		return selectedVoltage;
	}

	public void setSelectedVoltage(int selectedVoltage) {
		this.selectedVoltage = selectedVoltage;
	}

	public String getPrivateSubStationName() {
		return privateSubStationName;
	}

	public void setPrivateSubStationName(String privateSubStationName) {
		this.privateSubStationName = privateSubStationName;
	}

}
